package com.gopay.checkorder.service.impl;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.log4j.Logger;

import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.KuaiQianConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.bank.kuaiqian.ebank.KuaiQianQueryMessage;
import com.gopay.common.domain.bank.kuaiqian.ebank.KuaiQianQueryResultMessage;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.util.DateUtils;
import com.gopay.remote.bank.BankInteractRemoteService;

/**
 * 99BILL直连订单查询类
 * 
 * @CheckOrderKuaiQianImpl.java
 * @author Ryan
 * @2013-12-4 下午5:57:06 www.gopay.com.cn Inc.All rights reserved.
 */
public class CheckOrderKuaiQianImpl implements BankOrderService {
	private final static Logger logger = Logger.getLogger("KUAIQIAN");
	@Resource(name = "bankClient")
	private BankInteractRemoteService bankClient;

	@Override
	public CheckOrderResult checkOrder(BankOrder bankOrder, String arg1) {
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setOrderId(bankOrder.getOrderId());
		checkOrderResult.setSuccess(false);
		KuaiQianQueryMessage message = new KuaiQianQueryMessage();

		message.setOrderId(bankOrder.getOrderId()); // 国付宝系统订单号
		message.setBankOrderId(bankOrder.getOutOrderId());
		message.setBank(BankConstants.BANK_LOGO_KUAIQIAN);
		message.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));
		message.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));
		message.setOrderDate(DateUtils.format(bankOrder.getSendBankTm(),
				"yyyyMMddHHmmss"));
		message.setBank(bankOrder.getBankCode());
		Result result = new Result();
		try {
			result = bankClient.query(message);

			if (result == null || !result.isSuccess()) {
				logger.error("bankClient fail. result is null");

				if (result == null
						|| ProcCodeConstants.PROC_CODE_100E6037.equals(result
								.getResultCode())) {
					BankCountDownLatch.failIncrease(bankOrder.getBankCode());
				}
				checkOrderResult
						.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("系统返回对账结果为空");
				return checkOrderResult;
			}

			KuaiQianQueryResultMessage res = (KuaiQianQueryResultMessage) result
					.getDefaultModel();
			logger.error("KuaiQian query result："
					+ ToStringBuilder.reflectionToString(res));
			if (res == null) {
				// 查询结果为空
				logger.error("fail:orderId:" + bankOrder.getOrderId()
						+ " err:umpay bis query is null.");
				checkOrderResult
						.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("银行返回对账结果为空");
				return checkOrderResult;
			}
			String retCode = res.getPayResult(); // 返回码
			String errorCode = res.getErrCode(); // 交易错误码
			String tradeStatus = res.getPayResult(); // 订单状态

			// 快钱只返回成功的订单,错误码为空，则表示查询交易处理成功,否则处理失败
			if (StringUtils.isEmpty(res.getErrCode())) {
				// 成功处理
				if (KuaiQianConstants.PRO_ORDER_SUCCESS.equals(tradeStatus)) {
					// 交易成功
					checkOrderResult.setSuccess(true);
					// 组装入账对象
					InAccInfo accInfo = new InAccInfo();
					accInfo.setOrderId(bankOrder.getOrderId());
					//accInfo.setAmount(new BigDecimal(MoneyUtil.formatAmt(res.getPayAmount())));
					accInfo.setAmount(new BigDecimal("0.01"));
					accInfo.setRetCode("00");
					accInfo.setCardType(BankCardType.Unknown.toString());
					checkOrderResult.setAccInfo(accInfo);
					logger.error("快钱网银直连B2C订单：" + bankOrder.getOrderId()
							+ "的交易成功" + "返回码：" + retCode + "返回信息：交易处理成功");

				}
			} else {
				// 失败处理
				if (KuaiQianConstants.PRO_TRANS_FAILED_31005.equals(res
						.getErrCode())) {
					// 交易失败
					checkOrderResult.setBankFailure(true);
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易失败");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：交易失败" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_00000.equals(res
						.getErrCode())) {
					// 未知错误
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易未知错误");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：未知错误" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10001.equals(res
						.getErrCode())) {
					// 网关版本号不正确或不存在
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易网关版本号不正确或不存在");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息： 网关版本号不正确或不存在" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10002.equals(res
						.getErrCode())) {
					// 签名类型不正确或不存在
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易签名类型不正确或不存在");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：签名类型不正确或不存在" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10003.equals(res
						.getErrCode())) {
					// 人民币账号格式不正确
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易人民币账号格式不正确");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：人民币账号格式不正确" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10004.equals(res
						.getErrCode())) {
					// 查询方式不正确或不存在
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易查询方式不正确或不存在");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：查询方式不正确或不存在" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10005.equals(res
						.getErrCode())) {
					// 查询模式不正确或不存在"
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易查询模式不正确或不存在");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：查询模式不正确或不存在" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10006.equals(res
						.getErrCode())) {
					// 查询开始时间不正确
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易查询开始时间不正确");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息： 查询开始时间不正确" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10007.equals(res
						.getErrCode())) {
					// 查询结束时间不正确
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易查询结束时间不正确");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：查询结束时间不正确" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10008.equals(res
						.getErrCode())) {
					// 商户订单号格式不正确
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易商户订单号格式不正确");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：商户订单号格式不正确" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_10010.equals(res
						.getErrCode())) {
					// 字符集输入不正确
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易字符集输入不正确");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：字符集输入不正确" + "错误码："
							+ errorCode);
				}

				else if (KuaiQianConstants.PRO_TRANS_FAILED_11001.equals(res
						.getErrCode())) {
					// 开始时间不能在结束时间之后
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易开始时间不能在结束时间之后");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：开始时间不能在结束时间之后" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_11002.equals(res
						.getErrCode())) {
					// 允许查询的时间段最长为30 天
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易允许查询的时间段最长为30 天");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：允许查询的时间段最长为30 天" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_11003.equals(res
						.getErrCode())) {
					// 签名字符串不匹配
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易签名字符串不匹配");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息： 签名字符串不匹配" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_11004.equals(res
						.getErrCode())) {
					// 查询结束时间晚于当前时间
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易查询结束时间晚于当前时间");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：查询结束时间晚于当前时间" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_20001.equals(res
						.getErrCode())) {
					// 返回信息：该账号不存在或已注销
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易该账号不存在或已注销");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：该账号不存在或已注销" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_20002.equals(res
						.getErrCode())) {
					// 签名字符串不匹配，您无权查询
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回交易签名字符串不匹配，您无权查询");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：签名字符串不匹配，您无权查询" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_30001.equals(res
						.getErrCode())) {
					// 系统繁忙，请稍后再查询
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回系统繁忙，请稍后再查询");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：系统繁忙，请稍后再查询" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_30002.equals(res
						.getErrCode())) {
					// 查询过程异常，请稍后再试
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回查询过程异常，请稍后再试");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：查询过程异常，请稍后再试" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_31001.equals(res
						.getErrCode())) {
					// 本时间段内无交易记录
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回本时间段内无交易记录");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：本时间段内无交易记录" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_31002.equals(res
						.getErrCode())) {
					// 本时间段内无成功交易记录
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回本时间段内无成功交易记录");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：本时间段内无成功交易记录" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_31003.equals(res
						.getErrCode())) {
					// 商户订单号不存在
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回商户订单号不存在");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：商户订单号不存在" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_31004.equals(res
						.getErrCode())) {
					// 查询结果超出能允许的文件范围
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回查询结果超出能允许的文件范围");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：查询结果超出能允许的文件范围" + "错误码："
							+ errorCode);
				} else if (KuaiQianConstants.PRO_TRANS_FAILED_31006.equals(res
						.getErrCode())) {
					// 当前记录集页码不存在
					checkOrderResult
							.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
					checkOrderResult.setErrMsg("对账成功，银行返回当前记录集页码不存在");
					logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易失败"
							+ "返回码：" + retCode + "返回信息：当前记录集页码不存在" + "错误码："
							+ errorCode);
				} else {
		            // 银行订单状态未知
		            checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
		            checkOrderResult.setErrMsg("对账成功，银行返回未知错误");
		            logger.error("快钱直连B2C订单：" + bankOrder.getOrderId() + "的交易未知"
							+ "返回码：" + retCode+ "错误码："
							+ errorCode);
	
		          }
		        }
			return checkOrderResult;
		} catch (Exception e) {
			logger.error("bankClient fail.", e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("银行对账异常");
			return checkOrderResult;
		}
	}

	@Override
	public BankOrder getDbOrder() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public BaseMessage dayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<CheckOrderResult> checkDayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Result getDayendMsg(String string) {
		// TODO Auto-generated method stub
		return null;
	}


	@Override
	public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
		// TODO Auto-generated method stub
		return null;
	}

}
